共计 9555 个字符,预计需要花费 24 分钟才能阅读完成。
引入
1. 单文件组件
在很多 Vue 项目中,我们使用 Vue.component
来定义全局组件,紧接着用 new Vue({el: '#container'})
在每个页面内指定一个容器元素
Vue-cli 创建项目
一. 安装 Node.js
1.Node.js 介绍
- Node.js 是一个新的后端 (后台) 语言, 它的语法和 JavaScript 类似, 所以可以说它是属于前端的后端语
2. 前后端语言的区别
- 运行环境 : 后端语言 一般运行在服务器端,前端语言 运行在客户端的浏览器上
- 功能 : 后端语言 可以操作文件,可以读写数据库,前端语言 不能操作文件,不能读写数据库
3.Node.js 版本选择
- 我们一般安装 LTS (长期支持版本 Long-Time Support)
- 下载地址 : https://nodejs.org/en/
- 一直下一步下一步安装完成
4.Node.js 版本两大分支
- 官方发布的 node.js 版本 : 0.xx.xx 这种版本号就是官方发布的版本
- 社区发布的 node.js 版本 : xx.xx.x 就是社区开发的版本
5. 添加到环境变量
- 在 cmd 窗口输入
node -v
查看当前 Node.js 版本
二.npm
1.npm 介绍
- 在安装 node.js 完成后,在 node.js 中会同时帮我们安装一个 npm 包管理器 npm
- 我们可以借助 npm 命令来安装 node.js 的包; 这个工具相当于 python 的 pip 管理器
2.npm 常用命令
npm install -g [包名] # 安装模块 - g 表示全局安装,如果没有 -g,则表示在当前项目安装
npm list # 查看当前目录下已安装的 node 包
npm view [包名] engines # 查看包所依赖的 Node 的版本
npm outdated # 检查包是否已经过时,命令会列出所有已过时的包
npm update [包名] # 更新 node 包
npm uninstall [包名] # 卸载 node 包
npm [命令] -h # 查看指定命令的帮助文档
3. 常用选项
选项 | 说明 |
---|---|
-g | 全局安装, 写入系统环境变量 |
-S | --save, 把依赖加入到 package.json 中 |
-register= | 指定镜像仓库安装 |
三.cnpm
1.cnpm 介绍
- 因为 npm 的服务器位于国外可能会影响安装 (下载速度慢)
- 于是淘宝团队自己做了个国内的镜像, 淘宝镜像与官方同步频率目前为 10 分钟 一次以保证尽量与官方服务同步
2. 安装 cnpm
- cmd 窗口执行命令
npm install cnpm -g --registry=https://registry.npm.taobao.org
cnpm -v
来测试是否成功安装
3. 改变 npm 的下载地址
- 如果要使用淘宝的镜像我们可以将 npm 的下载地址进行更换, 以此来达到不安装 cnpm 也能使用淘宝镜像的目的
# npm 的默认地址是 : https://registry.npmjs.org/
# 换成淘宝
npm config set registry http://registry.npm.taobao.org/
# 换成官方(换回来)
npm config set registry https://registry.npmjs.org/
- 使用
npm config get registry
命令查看 npm 的仓库地址
四.Vue-CLI 脚手架
1.Vue-CLI 介绍
- 通过 @vue/cli 实现的交互式的项目脚手架
- 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发
- 一个运行时依赖 (@vue/cli-service),该依赖:
- 可升级
- 基于 webpack 构建,并带有合理的默认配置
- 可以通过项目内的配置文件进行配置
- 可以通过插件进行扩展
- 一个丰富的官方插件集合,集成了前端生态中最好的工具
- 一套完全图形化的创建和管理 Vue.js 项目的用户界面
2. 安装 cli 脚手架
- cmd 窗口执行
npm install -g @vue/cli
- 查看是否安装成功 / 版本
vue --version
五. 命令行创建 Vue 项目
1. 进入到目标目录
vue create [项目名]
# 示例
vue create vue_test
2. 选择配置
- 第一次一般选择手动配置
Manually select features
- 键盘上下键选择, 回车键确认并进行下一步
3. 选择项目所需要的功能
- 空格进行选中和取消, 回车确认并进行下一步
- 额外添加
Router
(路由, 用于页面跳转) 和Vuex
(状态管理器)功能
3. 选择 Vue 的版本
- 选择 2.x 版本
4. 询问是否使用历史路由模式
- 选择
n
不使用
5. 选择依赖管理文件
- 选择
package.json
这个文件
6. 是否保存本次配置
- 如果想让下次创建项目的时候使用本次配置, 那么就可以保存此次配置并取一个名字, 下次可以直接选择
- 等待创建:
- 创建成功:
7. 启动 / 停止项目
# 启动, 需要进入项目根目录
npm run serve
# 停止
ctrl+c
8. 打包项目
# 需要在项目根目录下进行打包操作
npm run build
六.UI 界面创建 Vue 项目
1.cmd 窗口输入命令
vue ui
2. 自动跳转到网页
3. 点击创建, 按照提示创建
- 等待其创建成功(1~3 分钟)
七.Pycharm 打开 Vue 项目
1. 左上角 File---->open----> 选择你的 Vue 项目
2. 设置 Vue 项目启动按钮
- Pycharm 打开 Vue 项目后默认是没有启动按钮的, 需要到 Terminal 中手动启动
- 我们可以进行添加配置, 让其支持启动按钮
3. 选择 npm
4. 设置启动命令及名字
5. 启动按钮变绿说明设置成功
6. 点击按钮启动 Vue 项目
八.Vue 项目目录介绍
dist: # 打包的项目目录(打包后会生成:npm run build)
node_modules: # 项目依赖(上传到 git 或者将项目拷贝给别人的时候删掉, 不然下载慢, 使用 npm install 命令可以重新安装)
public: # 共用资源
--favicon.ico0: # 图标
--index.html: # 项目入口页面,单页面
src: # 项目目标, 书写代码的地方
-- assets: # 资源
-- components: # 小组件
-- views: # 视图组件
-- App.vue: # 根组件
-- main.js: # 入口 js
-- router.js: # 路由文件
-- store.js: # 状态库文件
vue.config.js: # 项目配置文件(没有可以自己新建)
package.json:# 项目配置依赖(等同于 python 项目的 reqirement.txt,npm 安装包时指定的 "-S" 选项就是保存到这里面)
- 项目配置依赖文件 : package.json
"scripts": {
"serve": "vue-cli-service serve", # 运行项目, 可以修改 serve 成别的名字, 启动项目时就需要使用你指定的名字
"build": "vue-cli-service build", # 编译项目成 html,css,js
},
- 配置文件 vue.config.js (是一个可选的配置文件)
// 官网配置参考 : https://cli.vuejs.org/zh/config/
- vue 后缀文件
<template>
<!-- 模板区域 -->
</template>
<script>
// 逻辑代码区域
// 该语法和 script 绑定出现
//export default-->es6 的默认导出(导出一个对象),模拟 commonJS 的导出方式制定的
export default { }
</script>
<style scoped>
/* 样式区域 */
/* scoped 表示这里的样式只适用于组件内部, scoped 与 style 绑定出现 */
</style>
九.vue 项目中集成 axios
1. 安装 axios 模块
npm install -S axios # -S 选项会将该模块加到 package.json 中去
npm install --save axios
2. 为项目配置全局 axios
- 在入口 js 文件中书写
import axios from 'axios'
// 导入安装的模块不用加相对路径
Vue.prototype.$axios = axios
// 向 Vue 的原型中放一个属性 (key) 为 $axios,值为:axios
// 注意 $axios 是你自己取的名字还可以叫 xxxx, 尽量不要重复
- 使用
// 加入到 Vue 原型中以后之需要通过 this 就可以拿到 axios 发送请求了
methods:{handle(){
// 发送请求获取数据
this.$axios.get('/ajax/moreClassicList?').then(res =>{console.log(res.data)
})
}
}
3. 非全局配置使用
- 在某个组件中直接导入 axios
// 名字自己取 $axios 或者 xxxx, 不要重名
import $axios from 'axios'
- 然后直接使用你定义的名字来发送请求
methods:{handle(){
// 发送请求获取数据
$axios.get('/ajax/moreClassicList?',{}).then(res =>{console.log(res.data)
})
}
}
十. 设置 vue 前端代理解决跨域问题
1. 原理图
2. 配置代理
- 在 vue.config.js 中书写 (没有文件则新建一个)
- 以猫眼电影为例 : https://m.maoyan.com/#movie
module.exports = {
devServer: {
proxy: {
'/ajax': {
target: 'https://m.maoyan.com/',
changeOrigin: true
}
}
}
}
- 在组件中发送请求时
import $axios from 'axios'
mounted () {
// ajax/ 就是 'https://m.maoyan.com/ajax/'
$axios.get('ajax/moreClassicList?sortId=1&showType=3').then(res => {console.log(res.data)
})
}
十一. 补充 ES6 版本的导入导出
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到 export default
命令
1. 示例
- export-default.js 文件
export default function () { // 导出一个函数
console.log('foo');
}
- import-from.js 文件
import custom_test from './export-default'; // 导入这个文件导出的内容
custom_test(); // 'foo', 导出的就是上面的一个函数, 输出 "foo"
十二. 实战 : 使用 Vue-cli 创建项目并与后端联通
1. 需求
- 与后端联通(使用 Django), 并可以进行登入, 返回 token
- 可以获取到猫眼电影的电影数据(需要设置前端代理解决跨域问题)
ps : 后端虚拟环境搭建去看 路飞学城项目
2.Vue 项目代码示例
- router ---> index.js 添加路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Order from '../views/Order.vue'
import Login from '../views/Login.vue'
Vue.use(VueRouter)
const routes = [
{ // 登入
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue') // 就是 About
},
{ // 猫眼电影数据获取
path: '/order',
name: 'Order',
component: Order
},
]
const router = new VueRouter({routes})
export default router
- 在项目根路径下的 vue.config.js 文件设置代理
module.exports = {
devServer:{
proxy:{
'/api':{ // 代理 Django 后端
target:'http://127.0.0.1:8000/',
},
'/ajax':{ // 代理猫眼
target:'https://m.maoyan.com/'
},
}
}
}
- 将
axios
添加到 Vue 原型中去, 让其可以全局使用 : main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 导入 'axios'
import axios from 'axios'
Vue.config.productionTip = false
// 向 Vue 的原型中放一个 属性为:$axios,值为:axios, 其他组件页面使用直接 this.$axios
Vue.prototype.$axios = axios
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
- views ----> Home.vue
<template>
<div class="about">
<h1 class="title">This is an home page</h1>
<p> 用户名: <input type="text" v-model="username"></p>
<p> 密码: <input type="password" v-model="password"></p>
<hr>
<button @click="submit"> 登入 </button>
<p> 返回的 token:<br>{{token}}</p>
</div>
</template>
<script>
// 名字自己取 $axios 或者 xxxx, 不要重名
import $axios from 'axios'
export default {
name: 'Home',
data() {
return {
username: '',
password: '',
token: '',
}
},
methods: {submit() {console.log(this.username)
console.log(this.password)
// 发送 ajax 请求, 使用代理接口
// '/api/' 就等同于 'http://127.0.0.1:8000/api/'
$axios.post('/api/login/', {
username: this.username, // 将输入框的名字个密码发送给后端
password: this.password,
}).then(
res => {if (res.data.status === 200) {this.token = res.data.token}
}
).catch(res => {alert('登入失败')
})
}
},
}
</script>
<style>
.title {background-color: darkcyan;}
</style>
- views ----> Order.vue
<template>
<div class="about">
<h1 @click="handle"> 点击获取数据 </h1>
<div v-html="res"></div>
</div>
</template>
<script>
export default {
name:'Order',
data(){
return{res:''}
},
methods:{handle(){
// 发送 ajax 请求获取数据, 前缀在代理里面设置
this.$axios.get('/ajax/moreClassicList?sortId=1&showType=3').then(res =>{console.log(res.data) // 是一个 HTML 格式的数据
this.res = res.data // 可以直接使用 v -html 进行数据渲染
})
},
},
}
</script>
- src ---> App.vue (根组件)
<template>
<div id="app">
<div class="nav">
<!--router-link 进行路由跳转 -->
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/order">Order</router-link>
</div>
<router-view/> <!-- 路由跳转必须要书写这个 -->
</div>
</template>
<script>
export default {
name: 'App',
components: {}}
</script>
<!-- 这下面的都是样式, 不需要的可以删除 -->
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {padding: 30px;}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {color: #42b983;}
</style>
3.django 代码示例
写一个简单的登入接口 + 签发 token 就可以
- models.py
from django.db import models
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
email = models.CharField(max_length=32)
phone = models.BigIntegerField()
def __str__(self):
return self.username
- serializer.py 多方式登入
from django.db.models import Q # 用来构建或与非
from rest_framework.exceptions import ValidationError
from rest_framework import serializers
# 导入 jwt 配置文件
from rest_framework_jwt.settings import api_settings
# 将获取 payload 的方法以及签发 token 的方法内存地址赋值给两个变量
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
from user import models
# 多登入方式序列化类
class VariousLoginModelSerializer(serializers.ModelSerializer):
# 重写 username 字段让其时区字段自己的校验规则, 不然会出现 required 错误
username = serializers.CharField()
class Meta:
model = models.UserInfo
fields = ['username', 'password']
def validate(self, attrs):
username = attrs.get('username')
password = attrs.get('password')
# 多登入方式,username 可能是用户名、邮箱、手机号, 分情况操作
if username.isdigit():
user = models.UserInfo.objects.filter(Q(phone=int(username)) & Q(password=password)).first()
else:
user = models.UserInfo.objects.filter((Q(email=username) | Q(username=username)) & Q(password=password)).first()
if user:
# 登入成功, 签发 token
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
# context 是上下文,是视图类和序列化类沟通的桥梁(管道)
self.context['token'] = token
self.context['username'] = username
self.context['user_obj'] = user # 将当前 user 对象也放进去
return attrs
else:
raise ValidationError('用户名或密码错误!!')
- views.py
from rest_framework.generics import CreateAPIView
from user import models
from user import serializer
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin
# 多种登入方式(继承 ViewSetMixin 自动生成路由)
class VariousLoginView(ViewSetMixin, CreateAPIView):
queryset = models.UserInfo.objects.all()
serializer_class = serializer.VariousLoginModelSerializer
def create(self, request, *args, **kwargs):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
# 从 context 中取出序列化类传过来的数据
token = ser.context['token']
username = ser.context['username']
user_obj = ser.context['user_obj'] # 拿到 user 对象
return Response({'status': 200, 'msg': '登入成功!!', 'token': token, 'username': user_obj.username})
else:
return Response({'status': 100, 'msg': ser.errors})
def get(self, request, *args, **kwargs):
return Response({'status': 200, 'msg': 'ok',})
- urls.py
from django.contrib import admin
from django.urls import path,include
from user import views
from rest_framework.routers import SimpleRouter # 自动添加路由
router = SimpleRouter()
router.register('api/login',views.VariousLoginView)
urlpatterns = [path('admin/', admin.site.urls),
path('', include(router.urls)),
]
4. 测试
- 登入返回 token + 获取猫眼电影数据
- 多方式登入返回 token
正文完